package bapi

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"go-programming-tour-book/grpc-demo/pkg/errcode"
	"io/ioutil"
	"net/http"
)

const (
	APP_KEY    = "sam"
	APP_SECRET = "123456789"
)

type AccessToken struct {
	Token string `json:"token"`
}

type API struct {
	URL string
}

func NewAPI(url string) *API {
	return &API{
		URL: url,
	}
}

func (a *API) getAccesstToken(ctx context.Context) (string, error) {
	data := make(map[string]interface{})

	data["app_key"] = APP_KEY

	data["app_secret"] = APP_SECRET

	body, err := a.httpPost("auth", data)

	if err != nil {
		return "", err
	}

	var accessToken AccessToken

	_ = json.Unmarshal(body, &accessToken)

	return accessToken.Token, nil
}

func (a *API) httpGet(ctx context.Context, path string) ([]byte, error) {
	resp, err := http.Get(fmt.Sprintf("%s/%s", a.URL, path))

	if err != nil {
		return nil, err
	}

	defer resp.Body.Close()

	body, _ := ioutil.ReadAll(resp.Body)

	return body, nil
}

func (a *API) httpPost(path string, data interface{}) ([]byte, error) {
	jsonStr, _ := json.Marshal(data)

	resp, err := http.Post(fmt.Sprintf("%s/%s", a.URL, path), "application/json", bytes.NewBuffer(jsonStr))

	if err != nil {
		return nil, err
	}

	defer resp.Body.Close()

	body, _ := ioutil.ReadAll(resp.Body)

	return body, nil
}

func (a *API) GetTagList(ctx context.Context, name string) ([]byte, error) {
	token, err := a.getAccesstToken(ctx)

	if err != nil {
		return nil, err
	}

	body, err := a.httpGet(ctx, fmt.Sprintf(
		"%s?token=%s&name=%s",
		"api/v1/tags",
		token,
		name,
	))

	if err != nil {
		return nil, errcode.TogRPCError(errcode.ErrorGetTagListFail)
	}

	return body, nil
}
